//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Globalization;
using Microsoft.Practices.EnterpriseLibrary.Configuration.Design;
using EntLibContrib.Resource.Properties;

namespace EntLibContrib.Resource.Configuration.Design
{
	/// <summary>
	/// This class builds the hierarchy node structure from an existing configuration
	/// to populate the console from configuration data.
	/// </summary>
	public class ResourceSettingsNodeBuilder : NodeBuilder
	{
		#region Fields
		private ResourceSettings resourceSettings;
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="ResourceSettingsNodeBuilder"/> class.
		/// </summary>
		/// <param name="serviceProvider">The service provider.</param>
		/// <param name="resourceSettings">The resource settings.</param>
		public ResourceSettingsNodeBuilder (IServiceProvider serviceProvider, ResourceSettings resourceSettings)	: base(serviceProvider)
		{
			this.resourceSettings = resourceSettings;
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Builds this instance.
		/// </summary>
		/// <returns></returns>
		public ResourceSettingsNode Build ()
		{
			ResourceSettingsNode rootNode = new ResourceSettingsNode();

			// build the resource manager nodes
			ResourceManagerCollectionNode resourceManagerCollectionNode = new ResourceManagerCollectionNode();
			foreach (ResourceManagerDataBase resourceManagerData in resourceSettings.ResourceManagers)
			{
				BuildResourceManagerNode(rootNode, resourceManagerCollectionNode, resourceManagerData);
			}
			rootNode.AddNode(resourceManagerCollectionNode);

			// set the require permission mode
			rootNode.RequirePermission = resourceSettings.SectionInformation.RequirePermission;
			return rootNode;
		}
		#endregion

		#region Private Methods
		private void BuildResourceManagerNode(ResourceSettingsNode rootNode, ResourceManagerCollectionNode resourceManagerCollectionNode, ResourceManagerDataBase resourceManagerData)
		{
			ResourceManagerBaseNode resourceManagerNode = (ResourceManagerBaseNode)NodeCreationService.CreateNodeByDataType(resourceManagerData.GetType(), new object[] { resourceManagerData });
			if (resourceManagerNode == null)
				LogNodeMapError(rootNode, resourceManagerData.GetType());
			else
			{
				resourceManagerCollectionNode.AddNode(resourceManagerNode);
				if (resourceManagerNode.Name == resourceSettings.DefaultResourceManager)
					rootNode.DefaultResourceManager = resourceManagerNode;

				if (resourceManagerNode is ResourceManagerNode)
				{
					// special case for ResourceManagerNode
					BuildResourceProviderNode(resourceManagerNode, ((ResourceManagerData)resourceManagerData).ResourceProvider);
				}
			}
		}

		private void BuildResourceProviderNode(ResourceManagerBaseNode resourceManagerNode, string resourceProviderName)
		{
			if (string.IsNullOrEmpty(resourceProviderName))
				return;

			ResourceProviderDataBase resourceProviderData = resourceSettings.ResourceProviders.Get(resourceProviderName);
			if ( null == resourceProviderData )
			{
				LogError(resourceManagerNode, string.Format(CultureInfo.CurrentUICulture, InternalResources.ExceptionNoResourceProviderDefined, resourceProviderName));
				return;
			}

			ConfigurationNode resourceProviderNode = NodeCreationService.CreateNodeByDataType(resourceProviderData.GetType(), new object[] { resourceProviderData });
			if (null == resourceProviderNode)
			{
				LogNodeMapError(resourceManagerNode, resourceProviderData.GetType());
				return;
			}
			resourceManagerNode.AddNode(resourceProviderNode);
		}
		#endregion
	}
}